package simpledb.storage;

import simpledb.transaction.TransactionId;

/**
 * Page 是一个接口，表示缓冲池（BufferPool）中驻留的一个页面。它是数据库管理系统中用于管理磁盘数据读写的基本单位。
 * 每个页面对应磁盘文件中的一个固定大小的数据块（通常是 4KB 或 8KB）。
 * 当数据库操作需要访问某一页时，会先从磁盘加载到内存中的 Page 对象进行处理，并通过 BufferPool 管理这些对象的生命周期。
 * 此外，Page 接口还支持事务的脏页标记（dirty flag）、恢复前镜像（before image）等特性，是实现数据库事务持久性和恢复机制的关键部分。
 * <p>
 * 页面可能是“脏的”，表示自上次写入磁盘以来已被修改。
 * <p>
 * 出于恢复目的，Page 必须有一个如下形式的构造函数：
 *     Page(PageId id, byte[] data)
 */
public interface Page {

    /**
     * 返回此页面的唯一标识符（PageId）。
     * PageId 可以用来在磁盘上查找该页面，或判断该页面是否存在于缓冲池中。
     *
     * @return 当前页面的 PageId 对象
     */
    PageId getId();

    /**
     * 获取最后修改该页面的事务ID。
     * 如果页面未被修改（即干净状态），则返回 null。
     *
     * @return 最后一次将此页面标记为脏的事务ID，如果没有则返回 null
     */
    TransactionId isDirty();

    /**
     * 标记此页面为脏页，并记录是哪个事务引起的修改。
     * 若 dirty 为 false，则清除脏标记。
     *
     * @param dirty 是否标记为脏页
     * @param tid   引起该页面修改的事务ID
     */
    void markDirty(boolean dirty, TransactionId tid);

    /**
     * 生成一个字节数组，表示当前页面的内容。
     * 用于将页面序列化到磁盘。
     * <p>
     * 不变条件：由 getPageData() 生成的字节数组应该可以通过 Page 构造器还原出相同的页面对象。
     *
     * @return 表示当前页面内容的字节数组
     */
    byte[] getPageData();

    /**
     * 提供页面的“前镜像”（Before Image），即该页面在任何修改发生之前的状态。
     * 用于数据库的恢复机制（如回滚或崩溃恢复）。
     *
     * @return 页面的原始副本（未修改前）
     */
    Page getBeforeImage();

    /**
     * 当某个事务提交了对此页面的修改时，将当前页面内容复制到“前镜像”中，
     * 以便下一次修改可以基于最新的状态进行比较。
     */
    void setBeforeImage();
}
